package com.aliyun.messagemgt.web.controller;

import com.aliyun.messagemgt.application.service.MsgSourceService;
import com.aliyun.messagemgt.application.service.OperateLogService;
import com.aliyun.messagemgt.common.dto.response.ResultMap;
import com.aliyun.messagemgt.common.annotation.OperateLogAnnotation;
import com.aliyun.messagemgt.common.constants.MgtCommonConst;
import com.aliyun.messagemgt.common.enums.OperateTypeEnum;
import com.aliyun.messagemgt.common.enums.ResourceTypeEnum;
import com.aliyun.messagemgt.common.errorcode.CommonErrorCode;
import com.aliyun.messagemgt.common.exceptions.BaseException;
import com.aliyun.messagemgt.dto.MessageTemplate;
import com.aliyun.messagemgt.dto.MsgAdd;
import com.aliyun.messagemgt.dto.MsgSourceDto;
import com.aliyun.messagemgt.dto.OperateLog;
import com.aliyun.messagemgt.dto.query.BaseMessageSourceQuery;
import com.aliyun.messagemgt.dto.query.MsgQuery;
import com.aliyun.messagemgt.dto.vo.MsgSourceVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;

/**
 * @Description
 * @Author hzw
 * @Date 2020/12/21 10:48
 * @Version 1.0
 */
@Api(tags = "发送任务管理相关接口")
@RestController
@Slf4j
public class MsgSourceController {

    @Autowired
    private MsgSourceService msgSourceService;

    @Autowired
    private OperateLogService operateLogService;

    /**
     * 提交消息源
     * @param msgAdd
     * @return
     */
    @PostMapping("/msgSource/add")
    @OperateLogAnnotation(resouceType = ResourceTypeEnum.MSGSOURCE ,operateType = OperateTypeEnum.COMMIT,
            resouceClass = MsgAdd.class,resouceIdField = "msgSourceId")
    public Object msgSourceAdd(@RequestBody MsgAdd msgAdd){
        OperateLog operateLog = new OperateLog()
                .setOperateResourceType(ResourceTypeEnum.MSGSOURCE.getCode())
                .setModule(MgtCommonConst.MODULE_SMART_PUSH)
                .setOperateUser(msgAdd.getUserId())
                .setOperateUserName(msgAdd.getUserName())
                .setOperateDept(msgAdd.getDepartment())
                .setOperateDeptName(msgAdd.getDepartmentName())
                .setOperateTime(new Date())
                .setOperateResourceName(msgAdd.getSourceName());
        int i = 0;
        try {
            operateLog.setOperateType(OperateTypeEnum.COMMIT.getCode());
            i = (int)msgSourceService.addMsgSource(msgAdd);
            if(i <= 0){
                operateLog.setFailMsg(CommonErrorCode.FAIL_PUBLISH_SOURCE.errName());
                operateLog.setOperateStatus(MgtCommonConst.OPERATER_FAIL);
            }else{
                operateLog.setFailMsg(CommonErrorCode.SUCCESS_PUBLISH_SOURCE.errName());
                operateLog.setOperateStatus(MgtCommonConst.OPERATER_SUCCESS);
            }
        }catch (Exception e){
            log.error("msg source add error==={}",e);
            operateLog.setFailMsg(CommonErrorCode.FAIL_PUBLISH_SOURCE.errName());
            operateLog.setOperateStatus(MgtCommonConst.OPERATER_FAIL);
            if(e instanceof BaseException){
                throw e;
            }else{
                throw new RuntimeException("操作失败！");
            }
        }finally {
            operateLogService.insertOperateLog(operateLog);
        }
        return i;
    }

    /**
     * 保存消息源
     * @param msgAdd
     * @return
     */
    @RequestMapping("/msgSource/save")
    @OperateLogAnnotation(resouceType = ResourceTypeEnum.MSGSOURCE ,operateType = OperateTypeEnum.SAVE,
            resouceClass = MsgAdd.class,resouceIdField = "msgSourceId")
    public Object msgSourceSave(@RequestBody MsgAdd msgAdd){
        boolean addFlag = msgAdd.getMsgSourceId() == null ? true : false;
        String sourceName = msgAdd.getSourceName();
        if(!addFlag){
            MsgQuery msgQuery = new MsgQuery();
            msgQuery.setMsgSourceId(msgAdd.getMsgSourceId());
            MsgSourceVO msgSourceVO = msgSourceService.msgSourceDetail(msgQuery);
            if(msgSourceVO == null){
                throw new BaseException(CommonErrorCode.FAIL_UPDATE_SOURCE);
            }
            sourceName = msgSourceVO.getSourceName();
        }
        OperateLog operateLog = new OperateLog()
                .setOperateResourceType(ResourceTypeEnum.MSGSOURCE.getCode())
                .setModule(MgtCommonConst.MODULE_SMART_PUSH)
                .setOperateUser(msgAdd.getUserId())
                .setOperateUserName(msgAdd.getUserName())
                .setOperateDept(msgAdd.getDepartment())
                .setOperateDeptName(msgAdd.getDepartmentName())
                .setOperateTime(new Date())
                .setOperateResourceName(sourceName);
        int i = 0;

        try {
            i = (int)msgSourceService.saveMsgSource(msgAdd);
            if(i <= 0){
                if(!addFlag){
                    operateLog.setOperateType(OperateTypeEnum.MOD.getCode());
                    operateLog.setFailMsg(CommonErrorCode.FAIL_UPDATE_SOURCE.errName());
                }else{
                    operateLog.setOperateType(OperateTypeEnum.SAVE.getCode());
                    operateLog.setFailMsg(CommonErrorCode.FAIL_ADD_SOURCE.errName());
                }
                operateLog.setOperateStatus(MgtCommonConst.OPERATER_FAIL);
            }else{
                if(!addFlag){
                    operateLog.setOperateType(OperateTypeEnum.MOD.getCode());
                    operateLog.setFailMsg(CommonErrorCode.SUCCESS_UPDATE_SOURCE.errName());

                }else{
                    operateLog.setOperateType(OperateTypeEnum.SAVE.getCode());
                    operateLog.setFailMsg(CommonErrorCode.SUCCESS_ADD_SOURCE.errName());
                }
                operateLog.setOperateStatus(MgtCommonConst.OPERATER_SUCCESS);
            }
        }catch (Exception e){
            if(!addFlag){
                operateLog.setOperateType(OperateTypeEnum.MOD.getCode());
                operateLog.setFailMsg(CommonErrorCode.FAIL_UPDATE_SOURCE.errName());

            }else{
                operateLog.setOperateType(OperateTypeEnum.SAVE.getCode());
                operateLog.setFailMsg(CommonErrorCode.FAIL_ADD_SOURCE.errName());
            }
            operateLog.setOperateStatus(MgtCommonConst.OPERATER_FAIL);
            if(e instanceof BaseException){
                throw e;
            }else{
                log.error("消息源插入异常:{}",e.toString());
                throw new RuntimeException("操作失败！");
            }
        }finally {
            operateLogService.insertOperateLog(operateLog);
        }
        return i;
    }

    /**
     * 上下线消息源
     * @param msgAdd
     * @return
     */
    @RequestMapping("/msgSource/offLine")
    @OperateLogAnnotation(resouceType = ResourceTypeEnum.MSGSOURCE ,operateType = OperateTypeEnum.MOD,
            resouceClass = MsgAdd.class,resouceIdField = "msgSourceId")
    public Object msgSourceOffLine(@RequestBody MsgAdd msgAdd){
        // msgAdd.getAuditStatus() 1:下线， 2：发布
        boolean offLine = msgAdd.getAuditStatus() == 1 ? true : false;
        MsgQuery msgQuery = new MsgQuery();
        msgQuery.setMsgSourceId(msgAdd.getMsgSourceId());
        MsgSourceVO msgSourceVO = msgSourceService.msgSourceDetail(msgQuery);
        if(msgSourceVO == null){
            throw new BaseException(CommonErrorCode.FAIL_UPDATE_SOURCE);
        }
        String sourceName = msgSourceVO.getSourceName();
        OperateLog operateLog = new OperateLog()
                .setOperateResourceType(ResourceTypeEnum.MSGSOURCE.getCode())
                .setModule(MgtCommonConst.MODULE_SMART_PUSH)
                .setOperateUser(msgAdd.getUserId())
                .setOperateUserName(msgAdd.getUserName())
                .setOperateDept(msgAdd.getDepartment())
                .setOperateDeptName(msgAdd.getDepartmentName())
                .setOperateTime(new Date())
                .setOperateResourceId(Math.toIntExact(msgAdd.getMsgSourceId()))
                .setOperateResourceName(sourceName);
        int i = 0;

        try {
            i = (int)msgSourceService.modMsgSource(msgAdd);
            if(i <= 0){
                if(offLine){
                    operateLog.setOperateType(OperateTypeEnum.OFFLINE.getCode());
                    operateLog.setFailMsg(CommonErrorCode.FAIL_OFFLINE_SOURCE.errName());
                }else{
                    operateLog.setOperateType(OperateTypeEnum.COMMIT.getCode());
                    operateLog.setFailMsg(CommonErrorCode.FAIL_PUBLISH_SOURCE.errName());
                }
                operateLog.setOperateStatus(MgtCommonConst.OPERATER_FAIL);
            }else{
                if(offLine){
                    operateLog.setOperateType(OperateTypeEnum.OFFLINE.getCode());
                    operateLog.setFailMsg(CommonErrorCode.SUCCESS_OFFLINE_SOURCE.errName());
                }else{
                    operateLog.setOperateType(OperateTypeEnum.COMMIT.getCode());
                    operateLog.setFailMsg(CommonErrorCode.SUCCESS_PUBLISH_SOURCE.errName());
                }
                operateLog.setOperateStatus(MgtCommonConst.OPERATER_SUCCESS);
            }
        }catch (Exception e){
            if(offLine){
                operateLog.setOperateType(OperateTypeEnum.OFFLINE.getCode());
                operateLog.setFailMsg(CommonErrorCode.FAIL_OFFLINE_SOURCE.errName());

            }else{
                operateLog.setOperateType(OperateTypeEnum.COMMIT.getCode());
                operateLog.setFailMsg(CommonErrorCode.FAIL_PUBLISH_SOURCE.errName());
            }
            operateLog.setOperateStatus(MgtCommonConst.OPERATER_FAIL);
            if(e instanceof BaseException){
                throw e;
            }else{
                throw new RuntimeException("操作失败！");
            }
        }finally {
            operateLogService.insertOperateLog(operateLog);
        }
        return i;
    }

    /**
     * 消息源列表
     * @param msgQuery
     * @return
     */
    @PostMapping("/msgSource/list")
    public Object msgSourceList(@RequestBody MsgQuery msgQuery){
        return msgSourceService.listMsgSource(msgQuery);
    }

    /**
     * 消息源详情
     * @param msgQuery
     * @return
     */
    @RequestMapping("/msgSource/detail")
    public Object msgSourceDetail(@RequestBody MsgQuery msgQuery){
        return msgSourceService.msgSourceDetail(msgQuery);
    }

    /**
     * 消息分发列表
     * @param msgQuery
     * @return
     */
    @RequestMapping("/msgSource/message/list")
    public Object msgSourceMessageList(@RequestBody MsgQuery msgQuery){
        return msgSourceService.queryMsgList(msgQuery);
    }

    /**
     * 查询消息时部门筛选列表
     * @param msgQuery
     * @return
     */
    @RequestMapping("/msgSource/message/ownerDept")
    public Object msgSourceMessageOwnerDept(@RequestBody MsgQuery msgQuery){
        return  msgSourceService.listOwnerDeptForMessage(msgQuery);
    }

    /**
     * 查询消息源筛选部门列表
     * @param msgQuery
     * @return
     */
    @RequestMapping("/msgSource/ownerDept")
    public Object msgSourceOwnerDept(@RequestBody MsgQuery msgQuery){
        return msgSourceService.listOwnerDept(msgQuery);
    }

    /**
     * 删除
     * @param msgQuery
     * @return
     */
    @RequestMapping(value = "/msgSource/del")
    @OperateLogAnnotation(resouceType = ResourceTypeEnum.MSGSOURCE ,operateType = OperateTypeEnum.DEL,
            resouceClass = MsgQuery.class,resouceIdField = "msgSourceId")
    public Object deleteMsgSource(@RequestBody MsgQuery msgQuery){
        String sourceName = null;
        MsgSourceVO msgSourceVO = msgSourceService.msgSourceDetail(msgQuery);
        if(msgSourceVO == null){
            throw new BaseException(CommonErrorCode.FAIL_DELETE_SOURCE);
        }
        sourceName = msgSourceVO.getSourceName();
        OperateLog operateLog = new OperateLog()
                .setOperateResourceType(ResourceTypeEnum.MSGSOURCE.getCode())
                .setModule(MgtCommonConst.MODULE_SMART_PUSH)
                .setOperateUser(msgQuery.getUserId())
                .setOperateUserName(msgQuery.getUserName())
                .setOperateDept(msgQuery.getDepartment())
                .setOperateDeptName(msgQuery.getDepartmentName())
                .setOperateTime(new Date())
                .setOperateResourceId(Math.toIntExact(msgQuery.getMsgSourceId()))
                .setOperateType(OperateTypeEnum.DEL.getCode())
                .setOperateResourceName(sourceName);
        int i = 0;
        try {
            i = (int) msgSourceService.deleteMsgSource(msgQuery);
            if(i <= 0){
                operateLog.setFailMsg(CommonErrorCode.FAIL_DELETE_SOURCE.errName());
                operateLog.setOperateStatus(MgtCommonConst.OPERATER_FAIL);
            }else{
                operateLog.setFailMsg(CommonErrorCode.SUCCESS_DELETE_SOURCE.errName());
                operateLog.setOperateStatus(MgtCommonConst.OPERATER_SUCCESS);
            }
        }catch (Exception e){
            operateLog.setFailMsg(CommonErrorCode.FAIL_DELETE_SOURCE.errName());
            operateLog.setOperateStatus(MgtCommonConst.OPERATER_FAIL);
            if(e instanceof BaseException){
                throw e;
            }else{
                throw new RuntimeException("操作失败！");
            }
        }finally {
            operateLogService.insertOperateLog(operateLog);
        }
        return i;
    }

    /**
     * 获取消息类型
     * @return
     */
    @RequestMapping("/msgSource/listMessageTypes")
    public ResultMap listMessageTypes(@RequestBody MsgQuery msgQuery){
        return new ResultMap(msgSourceService.listMessageTypes());
    }

    @ApiOperation(value = "启停用")
    @PostMapping("/msgSource/updateStatus")
    @ResponseBody
    @ApiResponses(
            @ApiResponse(code = 200, message = "success", response = MessageTemplate.class)
    )
    public Object updateStatus(@RequestBody MsgSourceDto msgSourceDto){
        if (msgSourceDto.getMsgSourceId() == null || msgSourceDto.getIsEnabled() == null){
            throw new BaseException(CommonErrorCode.COMMON_PARAM_INVALID);
        }
        return msgSourceService.updateStatus(msgSourceDto);
    }

    @RequestMapping("/msgSource/noSpecifiedlist")
    public Object noSpecifiedlist(@RequestBody BaseMessageSourceQuery baseMessageSourceQuery){
        return msgSourceService.noSpecifiedBaseMessageSourcelist(baseMessageSourceQuery);
    }
}
